localStorage 的维护问题
在管理后台等复杂应用中,localStorage 可能存储了大量的状态数据(用户信息、权限数据、主题配置、菜单缓存等)。随着版本迭代,数据结构可能发生变化,如果不做维护策略,旧版本存储的数据可能导致新版本出现异常。
版本化存储策略
方案一:版本号标记
每次存储数据时附带版本号,读取时校验版本:
interface StorageItem<T> {
version: string
data: T
timestamp: number
}
function setStorage<T>(key: string, data: T, version: string): void {
const item: StorageItem<T> = {
version,
data,
timestamp: Date.now()
}
localStorage.setItem(key, JSON.stringify(item))
}
function getStorage<T>(key: string, currentVersion: string): T | null {
const raw = localStorage.getItem(key)
if (!raw) return null
const item: StorageItem<T> = JSON.parse(raw)
// 版本不匹配,清除旧数据
if (item.version !== currentVersion) {
localStorage.removeItem(key)
return null
}
return item.data
}
typescript
方案二:统一清除机制
在应用初始化时检查版本号,不匹配则清除全部 localStorage:
const APP_VERSION = '2.0.0'
function checkAndCleanStorage(): void {
const storedVersion = localStorage.getItem('app_version')
if (storedVersion !== APP_VERSION) {
// 保留部分必要数据(如语言偏好)
const lang = localStorage.getItem('locale')
localStorage.clear()
if (lang) localStorage.setItem('locale', lang)
localStorage.setItem('app_version', APP_VERSION)
}
}
typescript
过期时间策略
为缓存类数据设置过期时间:
function setWithExpiry<T>(key: string, data: T, ttlMs: number): void {
const item = {
data,
expiry: Date.now() + ttlMs
}
localStorage.setItem(key, JSON.stringify(item))
}
function getWithExpiry<T>(key: string): T | null {
const raw = localStorage.getItem(key)
if (!raw) return null
const item = JSON.parse(raw)
if (Date.now() > item.expiry) {
localStorage.removeItem(key)
return null
}
return item.data
}
typescript
存储容量监控
localStorage 容量约 5MB,需要监控使用量:
function getStorageSize(): string {
let total = 0
for (const key in localStorage) {
if (localStorage.hasOwnProperty(key)) {
total += localStorage.getItem(key)!.length * 2 // UTF-16 编码,每字符 2 字节
}
}
return (total / 1024 / 1024).toFixed(2) + ' MB'
}
typescript
最佳实践总结
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 版本号标记 | 每个存储项附带版本号 | 数据结构频繁变更的功能 |
| 统一清除 | 应用版本变更时清空 | 大版本升级 |
| 过期时间 | 数据携带 TTL | 缓存类数据(Token、列表缓存) |
| 容量监控 | 监控总存储量 | 数据量较大的应用 |
| 命名空间 | 使用前缀区分模块 | 多模块共享 localStorage |
↑